package org.idea.spring.look.up.safe;

import org.apache.catalina.User;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

/**
 * bean的依赖查找中安全性对比案例
 *
 * @Author linhao
 * @Date created in 8:58 上午 2021/4/12
 */
public class BeanLookUpSafe {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
        applicationContext.register(BeanLookUpSafe.class);
        applicationContext.refresh();
        displayBeanFactoryGetBean(applicationContext);
        displayObjectFactoryGetBean(applicationContext);
        displayObjectProviderGetIfAvailable(applicationContext);
        displayListableBeanFactoryGetBean(applicationContext);
        displayObjectFactoryGetBeanStream(applicationContext);
        applicationContext.close();
    }

    private static void displayObjectFactoryGetBeanStream(ApplicationContext applicationContext) {
        printBeansException("displayObjectFactoryGetBeanStream",() ->{
            ObjectProvider<User> userObjectProvider = applicationContext.getBeanProvider(User.class);
            userObjectProvider.stream().forEach(System.out::println);
        });
    }

    private static void displayListableBeanFactoryGetBean(ListableBeanFactory listableBeanFactory) {
        printBeansException("displayListableBeanFactoryGetBean",() ->{listableBeanFactory.getBeansOfType(User.class);});
    }

    private static void displayObjectProviderGetIfAvailable(AnnotationConfigApplicationContext applicationContext) {
        ObjectProvider<User> objectProvider = applicationContext.getBeanProvider(User.class);
        printBeansException("displayObjectProviderGetIfAvailable",() ->{objectProvider.getIfAvailable();});
    }

    private static void displayObjectFactoryGetBean(BeanFactory beanFactory) {
        ObjectFactory<User> objectFactory = beanFactory.getBeanProvider(User.class);
        printBeansException("displayObjectFactoryGetBean",()->{ objectFactory.getObject();});
    }

    private static void displayBeanFactoryGetBean(BeanFactory beanFactory) {
        printBeansException("displayBeanFactoryGetBean",()->{ beanFactory.getBean(User.class);});
    }

    private static void printBeansException(String source,Runnable runnable){
        try {
            System.err.println("==========================");
            System.err.println("Source is from :" + source);
            runnable.run();
        }catch (BeansException exception){
            exception.printStackTrace();
        }
    }

}
